/**
 * WidgetDomProvider
 */

 // $element, zoomProvider, dataProvider, historyProvider, storageProvider, constsProvider, toolProvider, area, transform, widget, page, opt
 function WidgetDomProvider(opts){
     this.$element = opts.element;
     this.zoomProvider = opts.zoomProvider;
     this.dataProvider = opts.dataProvider;
     this.historyProvider = opts.historyProvider;
     this.storageProvider = opts.storageProvider;
     this.constsProvider = opts.constsProvider;
     this.toolProvider = opts.toolProvider;
     this.area = opts.area;
     this.transform = opts.transform;
     this.position = opts.position;
     this.widget = opts.widget;
     this.page = opts.page;
     this.parseOpt(opts.opt);
     if (this.opt.positionable) setTimeout(this.setPositionable.bind(this), 500);
     this.widgetClassPrefix = "#wgt-id-";
     this.openWidgetStartPosition = {};
 }

 WidgetDomProvider.prototype = {
     Z_MAGNITUDE: 100,
     MIN_BUTTON_SIZE: 1,
     defaults: {
         positionable: true,
         draggable: true,
         resizable: true,
         aspectRatio: true
     },
     parseOpt: function(opt) {
         this.opt = $.extend(true, {}, $.extend(true, {}, this.defaults), opt);
         this.opt = $.extend(true, {}, this.opt);
         this.opt.id = this.widget.id;
     },
      draggable: function() {
         this.$element.draggable({
             containment: '.editor-canvas',
             handle: '.prevent-interaction',
             start: this.preventStart.bind(this),
             drag: this.broadcastPosition.bind(this),
             stop: this.debounceSavePosition.bind(this),
             transform: this.transform,
             area: this.area,
             widget: this.widget,
             zoomProvider: this.zoomProvider,
             snap: true
         });
     },
     bindEvent: function (){
         var _this = this;
         this.$element.click(function (){
             if (!this.storageProvider.data.nav.dragging){
                 setTimeout(function (){
                    _this.widget.pause = !_this.widget.pause;
                 }, 1);
             }
         });
     },
     setPositionable: function() {
         this.draggable();
         this.bindEvent();
         if (this.opt.resizable) this.resizable();
     },
     rePositionable: function() {
         try {
             this.$element.draggable('destroy');
             this.$element.resizable('destroy');
         } catch (ex) {}
         this.setPositionable();
     },
     resizable: function() {
         var minWidth, minHeight;
         if (this.widget.type == this.constsProvider.WIDGET_TYPE.GRAPH){
             minWidth = minHeight = this.MIN_BUTTON_SIZE;
         } else {
             minWidth = minHeight = 15;
         }
         // 红包组件不能resizable;
         if (this.widget.type == this.constsProvider.WIDGET_TYPE.REDBAG) return;
         this.$element.resizable({
             minWidth: minWidth,
             minHeight: minHeight,
             handles: 'e,s,n,w,ne, se, sw, nw',
             containment: '.editor-canvas',
             aspectRatio: this.opt.aspectRatio,
             start: this.preventStart.bind(this),
             resize: this.broadcastPosition.bind(this),
             stop: this.debounceSavePosition.bind(this),
             angle_x: this.widget.rotate_x,
             angle_y: this.widget.rotate_y,
             angle_z: this.widget.rotate_z,
             width: this.widget.width,
             height: this.widget.height,
             zoomProvider: this.zoomProvider,
         });
     },
     preventStart: function(e, ui) {
         var nav = this.storageProvider.data.nav;
         var position, scale;

         nav.dragging = true;
         if (nav.selectedWidgetIds.length <= 1){
             nav.selectedWidgetId = this.widget.id;
         }
         scale = this.zoomProvider.scale();
         position = this.position;
         position = {
             top: position.top,
             left: position.left / scale
         };
         this.startPosition = $.extend(true, {}, position);
         if (nav.selectedWidgetIds.length > 1) {
             var index, openWidgetIds;
             openWidgetIds = $.extend(true, {}, nav.selectedWidgetIds);
             index = openWidgetIds.indexOf(this.widget.id);
             openWidgetIds.splice(index, 1);
             for (var i = 0; i < openWidgetIds.length; i++) {
                 var widget_id, widgetEl, widgetPosition, widgetScope;
                 widget_id = openWidgetIds[i];
                 widgetEl = $(this.widgetClassPrefix + widget_id);
                 widgetPosition = widgetEl.position();
                 widgetPosition.left = widgetPosition.left / scale;
                 widgetScope = widgetEl.isolateScope();
                 this.openWidgetStartPosition[widget_id] = widgetPosition;

             };
             // 把原来的属性保存起来
             for (var i = 0; i < nav.selectedWidgetIds.length; i++) {
                 var widget_id, oldWidget;
                 widget_id = nav.selectedWidgetIds[i];
                 oldWidget = $.extend(true, {}, this.dataProvider.getSpecifyWidgetById(widget_id));

                 //this.dataProvider.oldWidgets[widget_id] = oldWidget;
             }
         }
     },
     broadcastPosition: function(ev, ui) {
         var position, scale;
         if (ui.size) {
             this.updateFontSize(ui);
             this.updatelineHeight(ui);
             this.workAroundBugInjQueryUI(ui);
             $.extend(true, {}, this.position, {
                 fontSize: this.toolProvider.getFontSizeByWidth(ui.position.height)
             });
         }
         if (!ui.size) {
             scale = this.zoomProvider.scale();
             position = {
                 left: ui.position.left / scale,
                 top: ui.position.top / scale,
             }
         } else {
             position = {
                 left: ui.position.left,
                 top: ui.position.top,
             }
         }
         $.extend(true, {}, this.position, position, ui.size);
         this.$element.css(position);
         // 让选中的一起移动
         this.positionTogether($.extend(true, {}, position));
         this.widget.history = false;
         //this.$scope.$broadcast('position', this.$scope.position);
     },
     fixPosition: function() {

     },
     positionTogether: function(position) {
         var nav = this.storageProvider.data.nav;
         if (nav.selectedWidgetIds.indexOf(this.widget.id) == -1) return;
         if (nav.selectedWidgetIds.length > 1) {
             var distanceTop, distanceLeft, index, openWidgetIds, scale;
             scale = this.zoomProvider.scale();
             distanceTop = position.top - this.startPosition.top;
             distanceLeft = position.left - this.startPosition.left;
             openWidgetIds = $.extend(true, {}, nav.selectedWidgetIds);
             index = openWidgetIds.indexOf(this.widget.id);
             openWidgetIds.splice(index, 1);

             for (var i = 0; i < openWidgetIds.length; i++) {
                 var widget_id, widgetEl, widgetScope, widgetStartPosition;
                 widget_id = openWidgetIds[i];
                 widgetEl = $(this.widgetClassPrefix + widget_id);
                //  widgetScope = widgetEl.isolateScope();
                 widgetStartPosition = $.extend(true, {}, this.openWidgetStartPosition[widget_id]);
                 widgetStartPosition.top += distanceTop;
                 widgetStartPosition.left += distanceLeft;
                 widgetEl.css(widgetStartPosition);
                 widgetScope.position = $.extend(true, {}, widgetScope.position, widgetStartPosition);

                 setTimeout(function() {
                    //  widgetScope.$broadcast('position');
                    //  widgetScope.widget.history = false;
                 }, i * 500);
             };
         }
     },
     updateFontSize: function(ui) {
         ui.element.css({
             'font-size': this.toolProvider.getFontSizeByWidth(ui.element.height()) + 'px'
         });
     },
     updatelineHeight: function(ui) {
         ui.element.css({

         });
     },
     workAroundBugInjQueryUI: function(ui) {
         var min = this.MIN_BUTTON_SIZE;
         if (ui.size.width < min || ui.size.height < min) {
             ui.size = this._lastValidSize || ui.originalSize;
             ui.position = this._lastValidposition || ui.originalPosition;
             ui.element.css(ui.size);
             ui.element.css(ui.position);
         } else {
             this._lastValidSize = $.extend(true, {}, ui.size);
             this._lastValidposition = $.extend(true, {}, ui.position);
         }
     },
     updatePositionModel: function() {
         var position, offset;
         offset = this.borderOffsetToCenterOffset(this.position);
         position = {
             offset_x: offset.x,
             offset_y: offset.y,
             width: this.position.width,
             height: this.position.height,
             fontSize: this.toolProvider.getFontSizeByWidth(this.position.height)
         };
         $.extend(true, {}, this.widget, position);
     },
     updateElementPositionWithOffset: function() {
         var dimensions = {
                 width: this.widget.width,
                 height: this.widget.height,
             },
             offset = {
                 x: this.widget.offset_x,
                 y: this.widget.offset_y
             },
             position;
         position = this.centerOffsetToBorderOffset(dimensions, offset);
         position = $.extend(true, {}, position, dimensions, {
             fontSize: is.AnimationApp.getFontSizeByWidth(dimensions.height),
             'font-size': is.AnimationApp.getFontSizeByWidth(dimensions.height) + 'px',
             zIndex: Math.round((this.widget.offset_z) * this.Z_MAGNITUDE),
             'z-index': Math.round((this.widget.offset_z) * this.Z_MAGNITUDE)
         });
         position = $.extend(true, {}, this.position, position);
         this.$element.css(position);
     },
     debounceSavePosition: function(ev, ui) {
         var nav = this.storageProvider.data.nav;

         nav.dragging = false;
         if (ui.size) {
             this.workAroundBugInjQueryUI(ui);
         }
         this.repositionModal();
         if (this.widget.property_changed) delete this.widget.property_changed;
         if (nav.selectedWidgetIds.length > 1) {
             var distanceTop, distanceLeft, index, openWidgetIds;
             openWidgetIds = $.extend(nav.selectedWidgetIds);
             index = openWidgetIds.indexOf(this.widget.id);
             openWidgetIds.splice(index, 1);

             // 插入批量属性改变命令中
             var oldWidgets = [],
                 newWidgets = [];
             for (var i = 0; i < nav.selectedWidgetIds.length; i++) {
                 var widget_id, widgetEl, widgetScope, oldWidget, newWidget;
                 widget_id = nav.selectedWidgetIds[i];

                 widgetEl = $(this.widgetClassPrefix + widget_id);
                 widgetScope = widgetEl.isolateScope();
                 widgetScope.widget.history = true;

                 widgetScope.savePosition();

                //  oldWidget = this.dataProvider.oldWidgets[widget_id];
                //  newWidget = this.dataProvider.getSpecifyWidgetById(widget_id);
                //  oldWidgets.push($.extend(true, {}, oldWidget));
                //  newWidgets.push($.extend(true, {}, newWidget));
             };

             //this.historyProvider.execute(new is.BatchWidgetPropertyCommand(this.dataProvider, oldWidgets, newWidgets));
         } else {
             //this.savePosition();
         }
     },
     repositionModal: function() {
        //  if (this.$scope.modal && !this.$scope.modal.detached) {
        //      this.$scope.modal.position();
        //  }
     },
     positionNewWidget: function(position) {
         var offset = position.offset || this.borderOffsetToCenterOffset(position);
         this.widget.offset_x = offset.x;
         this.widget.offset_y = offset.y;
         this.widget.width = position.width;
         this.widget.height = position.height;

     },
     /**
      * 边界坐标系转换成中心点坐标系，并且从大编辑坐标系转换到主题坐标系
      * @parma position 居于大编辑坐标系的边界坐标
      **/
     borderOffsetToCenterOffset: function(position) {
         var scale, centerOffset;
         scale = this.zoomProvider.scale();
         // widget.offset_x 为小数时小数会被四舍五入
         centerOffset = {
             x: Math.round(position.left + position.width / 2 - this.transform.offset_x),
             y: Math.round(this.transform.offset_y - position.top - position.height / 2)
         };
         return centerOffset;
     },
     /**
      * 中心点坐标系转换成边界坐标系，并且从主题坐标系转换到大编辑坐标系
      * @parma dimensions 主题尺寸
      * @parma offsets 居于主题坐标系的中心坐标
      **/
     centerOffsetToBorderOffset: function(dimensions, offsets) {
         var scale, borderOffset;
         scale = this.zoomProvider.scale();
         borderOffset = {
             left: this.transform.offset_x + offsets.x - dimensions.width / 2-0.5,
             top: this.transform.offset_y - offsets.y - dimensions.height / 2
         };
         return borderOffset;
     },
     getPosition: function() {
         var width, height, dimensions, coords;
         width = this.widget.width
         height = this.widget.height;
         dimensions = {
             width: Math.max(width, this.MIN_BUTTON_SIZE),
             height: Math.max(height, this.MIN_BUTTON_SIZE)
         };
         coords = this.centerOffsetToBorderOffset(dimensions, {
             x: this.widget.offset_x || 0,
             y: this.widget.offset_y || 0
         });
         return {
             left: Math.round(coords.left),
             top: Math.round(coords.top),
             width: Math.round(dimensions.width),
             height: Math.round(dimensions.height),
             zIndex: Math.round((this.widget.offset_z) * this.Z_MAGNITUDE),
             fontSize: this.toolProvider.getFontSizeByWidth(dimensions.height),
         };
     }
 };

 module.exports = WidgetDomProvider;
